#include "websocketserver/websocketserver.h"
#include <memory>
#include <thread>
#include <set>
#include <chrono>
using namespace hhfox;

namespace hhfox
{

    class BusinessHandlerA : public IWebSocketHandler
    {
    public:
        class ConnectionManager
        {
        public:
            using connection_hdl = websocketpp::connection_hdl;
            ConnectionManager(hhfox::WebSocketServer *svr)
                : svr_(svr) {}

            void Push(const connection_hdl &hdl)
            {
                {
                    std::unique_lock<std::recursive_mutex> lock(mtx_);
                    for (auto &it : cache_)
                    {
                        svr_->sendRawMessage(hdl, (char *)it.data(), it.size(),
                                             websocketpp::frame::opcode::binary);
                    }
                    conns_.insert(hdl);
                }
            }

            void Del(const connection_hdl &hdl)
            {
                std::unique_lock<std::recursive_mutex> lock(mtx_);
                conns_.erase(hdl);
            }

            void SendMessage(const std::string &buff)
            {
                return SendMessage((void *)buff.data(), buff.size());
            }

            void SendMessage(std::vector<char> buff)
            {
                return SendMessage(buff.data(), buff.size());
            }

            void SendMessage(void *buff, size_t len)
            {
                if (cache_.size() > 20)
                {
                    cache_.pop_front();
                }
                std::vector<char> it;
                it.assign((char *)buff, (char *)buff + len);
                cache_.push_back(std::move(it));
                if (Size() == 0)
                {
                    return;
                }
                std::unique_lock<std::recursive_mutex> lock(mtx_);
                for (auto &hdl : conns_)
                {
                    try
                    {
                        svr_->sendRawMessage(hdl, (char *)buff, len,
                                             websocketpp::frame::opcode::binary);
                    }
                    catch (websocketpp::exception const &e)
                    {
                    }
                }
            }

            size_t Size() const
            {
                std::unique_lock<std::recursive_mutex> lock(mtx_);
                return conns_.size();
            }

            std::vector<std::string> clientList() const
            {
                std::vector<std::string> v;
                std::unique_lock<std::recursive_mutex> lock(mtx_);
                for (auto &hdl : conns_)
                {
                    auto addr = svr_->get_con_from_hdl(hdl)->get_remote_endpoint();
                    v.push_back(addr);
                }
                return v;
            }

        private:
            hhfox::WebSocketServer *svr_;
            std::set<connection_hdl, std::owner_less<connection_hdl>> conns_;
            mutable std::recursive_mutex mtx_;
            std::deque<std::vector<char>> cache_;
        };
        BusinessHandlerA(WebSocketServer *server) : IWebSocketHandler(server),conn_mgr_(server) {}

        ~BusinessHandlerA() {}
        void onOpen(connection_hdl hdl) override
        {
            conn_mgr_.Push(hdl);
            // 处理业务 A 的连接打开事件
            std::cout << "BusinessHandlerA onOpen: \n";
            for(auto it:conn_mgr_.clientList()){
                std::cout << it << std::endl;
            }
        }

        void onClose(connection_hdl hdl) override
        {
            conn_mgr_.Del(hdl);
            // 处理业务 A 的连接关闭事件
            std::cout << "BusinessHandlerA onClose: \n";
        }

        void onHttp(connection_hdl hdl) override
        {
            // 处理业务 A 的 HTTP 请求
            std::cout << "BusinessHandlerA onHttp: \n";
        }

        void onMessage(connection_hdl hdl) override
        {
            // 处理业务 A 的消息接收事件
            std::cout << "BusinessHandlerA onMessage: \n";
            server_->sendRawMessage(hdl, "hello");
        }

    private:
        ConnectionManager conn_mgr_;
    };

    class BusinessHandlerB : public IWebSocketHandler
    {
    public:
        BusinessHandlerB(WebSocketServer *server) : IWebSocketHandler(server) {}

        ~BusinessHandlerB() {}

        void onOpen(connection_hdl hdl) override
        {
            // 处理业务 B 的连接打开事件
            std::cout << "BusinessHandlerB onOpen: \n";
        }

        void onClose(connection_hdl hdl) override
        {
            // 处理业务 B 的连接关闭事件
            std::cout << "BusinessHandlerB onClose: \n";
        }

        void onHttp(connection_hdl hdl) override
        {
            // 处理业务 B 的 HTTP 请求
            std::cout << "BusinessHandlerB onHttp: \n";
        }

        void onMessage(connection_hdl hdl) override
        {
            // 处理业务 B 的消息接收事件
            std::cout << "BusinessHandlerB onMessage: \n";
        }
    };
}

int main()
{
    // 创建 WebSocket 服务器
    hhfox::WebSocketServer server("127.0.0.1", 9002);
    server.setLoggerCallback([](int level, const std::string &file, int line, const std::string &msg)
                             {
                                if(level > 0 )
                                std::cout << "[" << level << "] " << file << ":" << line << ": " << msg <<std::endl; });
    // 创建业务处理器 A 和 B
    auto handlerA = std::make_shared<BusinessHandlerA>(&server);
    auto handlerB = std::make_shared<BusinessHandlerB>(&server);

    // 注册业务处理器
    server.registerHandler("/api/a", handlerA);
    server.registerHandler("/api/b", handlerB);

    // 启动服务器
    server.start();

    // 保持程序运行
    while (true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    return 0;
}